/* ether.h */

/* Ethernet packet format:

 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |  Dest. MAC (6)  |  Src. MAC (6)   |Type (2)|      Data (46-1500)...   |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/

#define	ETH_ADDR_LEN	6	/* Length of Ethernet (MAC) address	*/
typedef	unsigned char	Eaddr[ETH_ADDR_LEN];/* a physical Ethernet address*/

/* Ethernet packet header */

struct	etherPkt {
	byte	dst[ETH_ADDR_LEN];	/* Destination Mac address	*/
	byte	src[ETH_ADDR_LEN];	/* Source Mac address		*/
	uint16	type;			/* Ether type field		*/
	byte	data[1];		/* Packet payload		*/
};

#define	ETH_HDR_LEN		14	/* Length of Ethernet packet 	*/
					/*  header			*/

/* Ethernet DMA buffer sizes */

#define	ETH_MTU			1500	/* Maximum transmission unit	*/
#define	ETH_VLAN_LEN		4	/* Length of Ethernet vlan tag	*/
#define ETH_CRC_LEN		4	/* Length of CRC on Ethernet 	*/
					/*  frame			*/

#define	ETH_MAX_PKT_LEN	( ETH_HDR_LEN + ETH_VLAN_LEN + ETH_MTU )

#define	ETH_BUF_SIZE		2048	/* A multiple of 16 greater 	*/
					/* 	than the max packet 	*/
					/*  	size(cache alignment)	*/

/* State of the Ethernet interface */

#define	ETH_STATE_FREE		0	/* control block is unused 	*/
#define	ETH_STATE_DOWN		1	/* interface is currently  	*/
					/* 	inactive 		*/
#define	ETH_STATE_UP		2	/* interface is currently active*/

/* Ethernet device control functions */

#define	ETH_CTRL_GET_MAC     	1 	/* Get the MAC for this device	*/

/* Ethernet multicast */

#define ETH_NUM_MCAST		32     /* Max number of multicast addresses*/

/* Ehternet NIC type */

#define ETH_TYPE_3C905C 	1
#define ETH_TYPE_E100 		2

struct	ether	{
	byte	state; 		/* ETH_STATE_... as defined above 	*/
	struct	dentry	*phy;	/* physical eth device for Tx DMA 	*/
	byte 	type; 		/* NIC type_... as defined above 	*/

	/* Pointers to associated structures */

	struct	dentry	*dev;	/* address in device switch table	*/
	void	*csr;		/* addr.of control and status regs.	*/
	uint32	pcidev;		/* PCI device number			*/
	uint32	iobase;		/* I/O base from config			*/
	uint32  flashbase;      /* flash base from config	       	*/
    uint32	membase; 	/* memory base for device from config	*/

	void    *rxRing;	/* ptr to array of recv ring descriptors*/
	void    *rxBufs; 	/* ptr to Rx packet buffers in memory	*/
	uint32	rxHead;		/* Index of current head of Rx ring	*/
	uint32	rxTail;		/* Index of current tail of Rx ring	*/
	uint32	rxRingSize;	/* size of Rx ring descriptor array	*/
	uint32	rxIrq;		/* Count of Rx interrupt requests       */

	void    *txRing; 	/* ptr to array of xmit ring descriptors*/
	void    *txBufs; 	/* ptr to Tx packet buffers in memory	*/
	uint32	txHead;		/* Index of current head of Tx ring, cb_to_send	*/
	uint32	txTail;		/* Index of current tail of Tx ring, cb_to_use	*/
	uint32	txRingSize;	/* size of Tx ring descriptor array	*/
	uint32	txIrq;		/* Count of Tx interrupt requests       */

	uint8	devAddress[ETH_ADDR_LEN];/* MAC address 		*/

	uint8	addrLen;	/* Hardware address length	      	*/
	uint16	mtu;	    	/* Maximum transmission unit (payload)  */
	
	uint8 	cuc_cmd;

	uint32	errors;		/* Number of Ethernet errors 		*/
	sid32	isem;		/* Semaphore for Ethernet input		*/
	sid32	osem; 		/* Semaphore for Ethernet output	*/
	uint16	istart;		/* Index of next packet in the ring     */

	int16	inPool;		/* Buffer pool ID for input buffers 	*/
	int16	outPool;	/* Buffer pool ID for output buffers	*/

	int16 	proms; 		/* nonzero => promiscuous mode 		*/
    
	int16 	ed_mcset;       /* nonzero => multicast reception set   */
	int16 	ed_mcc;	 	/* count of multicast addresses		*/
    	Eaddr   ed_mca[ETH_NUM_MCAST];/* array of multicast addrs 	*/

	/* Late binding operations */

	void 	(*ethInit)(struct ether *ethptr);
	status 	(*ethOpen)(struct ether *ethptr);
	status 	(*ethClose)(struct ether *ethptr);
	devcall (*ethRead)(struct ether *ethptr, void *buf, uint32 len);
	devcall (*ethWrite)(struct ether *ethptr, void *buf, uint32 len);
	devcall (*ethControl)(struct ether *ethptr, int32 func, 
			int32 arg1, int32 arg2);
	interrupt (*ethInterrupt)(struct ether *ethptr);
};

extern	struct	ether	ethertab[];	/* array of control blocks      */

int32	colon2mac(char *, byte *);
int32	allocRxBuffer(struct ether *, int32);
int32	waitOnBit(volatile uint32 *, uint32, const int32, int32);

typedef	uint32	IPaddr;

enum scb_cmd_lo {
	cuc_nop        	= 0x00,
	ruc_start      	= 0x01,
	ruc_resume	= 0x02,
	ruc_recv_dma	= 0x03,
	ruc_abort	= 0x04,
	ruc_load_hds	= 0x05,
	ruc_load_base  	= 0x06,
	cuc_start      	= 0x10,
	cuc_resume     	= 0x20,
	cuc_dump_addr  	= 0x40,
	cuc_dump_stats 	= 0x50,
	cuc_load_base  	= 0x60,
	cuc_dump_reset 	= 0x70,
	cuc_stat_resume	= 0xA0,
};

#define X(a,b)	b,a

/* configuration byte map */
struct config {
	/*0*/	uint8 X(byte_count:6, pad0:2);
	/*1*/	uint8 X(X(rx_fifo_limit:4, tx_fifo_limit:3), pad1:1);
	/*2*/	uint8 adaptive_ifs;
	/*3*/	uint8 X(X(X(X(mwi_enable:1, type_enable:1), read_align_enable:1),
				   term_write_cache_line:1), pad3:4);
	/*4*/	uint8 X(rx_dma_max_count:7, pad4:1);
	/*5*/	uint8 X(tx_dma_max_count:7, dma_max_count_enable:1);
	/*6*/	uint8 X(X(X(X(X(X(X(late_scb_update:1, direct_rx_dma:1),
						   tno_intr:1), cna_intr:1), standard_tcb:1), standard_stat_counter:1),
				   rx_discard_overruns:1), rx_save_bad_frames:1);
	/*7*/	uint8 X(X(X(X(X(rx_discard_short_frames:1, tx_underrun_retry:2),
					   pad7:2), rx_extended_rfd:1), tx_two_frames_in_fifo:1),
				 tx_dynamic_tbd:1);
	/*8*/	uint8 X(X(mii_mode:1, pad8:6), csma_disabled:1);
	/*9*/	uint8 X(X(X(X(X(rx_tcpudp_checksum:1, pad9:3), vlan_arp_tco:1),
					 link_status_wake:1), arp_wake:1), mcmatch_wake:1);
	/*10*/	uint8 X(X(X(pad10:3, no_source_addr_insertion:1), preamble_length:2),
				 loopback:2);
	/*11*/	uint8 X(linear_priority:3, pad11:5);
	/*12*/	uint8 X(X(linear_priority_mode:1, pad12:3), ifs:4);
	/*13*/	uint8 ip_addr_lo;
	/*14*/	uint8 ip_addr_hi;
	/*15*/	uint8 X(X(X(X(X(X(X(promiscuous_mode:1, broadcast_disabled:1),
						   wait_after_win:1), pad15_1:1), ignore_ul_bit:1), crc_16_bit:1),
				   pad15_2:1), crs_or_cdt:1);
	/*16*/	uint8 fc_delay_lo;
	/*17*/	uint8 fc_delay_hi;
	/*18*/	uint8 X(X(X(X(X(rx_stripping:1, tx_padding:1), rx_crc_transfer:1),
					 rx_long_ok:1), fc_priority_threshold:3), pad18:1);
	/*19*/	uint8 X(X(X(X(X(X(X(addr_wake:1, magic_packet_disable:1),
						   fc_disable:1), fc_restop:1), fc_restart:1), fc_reject:1),
				   full_duplex_force:1), full_duplex_pin:1);
	/*20*/	uint8 X(X(X(pad20_1:5, fc_priority_location:1), multi_ia:1), pad20_2:1);
	/*21*/	uint8 X(X(pad21_1:3, multicast_all:1), pad21_2:4);
	/*22*/	/*uint8 X(X(rx_d102_mode:1, rx_vlan_drop:1), pad22:6);
	uint8 pad_d102[9];*/
};

/* Command Block Descriptor */

struct e100_tx_desc {
	uint16 status;	//descriptor's status
	uint16 command;	//descriptor's command word
	uint32 link;	//address of the next command block
	union  {
		struct{
			uint32 tbd_array; //transmit buffer descriptor array address
			uint16 tcb_byte_count; //transmit command block byte count
			uint8 threshold;
			uint8 tbd_num;
			byte data[ETH_BUF_SIZE];
		}tcb;
		uint8 macaddr[ETH_ADDR_LEN]; //Individual Address Setup
		struct config configure;
		uint32 dump_buffer_addr;
	}u;
	//struct e100_rx_desc *next;	//pointor to the next descriptor
};

char* dump_buffer;
